<template>
  <div
    class="w-full h-full bg-[#ffffffca] overflow-y-auto flex items-center flex-col"
    v-loading="loading"
    element-loading-text="pdf文件加载中..."
  >
    <canvas
      class="pdf-canvas"
      style="border-bottom: 1px solid #ccc"
      v-for="pageIndex in pdfPages"
      :id="`pdf-canvas-` + pageIndex"
      :key="pageIndex"
    ></canvas>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick, onMounted, watch } from "vue";
import * as PdfJs from "pdfjs-dist/legacy/build/pdf.js";
import workerEntry from "pdfjs-dist/build/pdf.worker.min.js?url";

const props = defineProps({
  url: {
    //文件地址
    type: String,
    default:
      "http://worktest.gysyjt.cn:22241/group1/M00/01/38/CgoS02ZegguADx3PAAMCNBJxQb0675.pdf",
  },
  pdfScale: {
    //页面缩放比例
    type: Number,
    default: 2,
  },
});

const loading = ref<boolean>(false);
// 文件总页数
const pdfPages = ref<number>(0);
// 页面缩放比例
let pdfDoc: any;

async function loadFile(url: string) {
  loading.value = true;
  PdfJs.GlobalWorkerOptions.workerSrc = workerEntry;
  const loadingTask = PdfJs.getDocument({
    url,
    cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.0.288/cmaps/", //字体库
    cMapPacked: true,
  });
  loadingTask.promise.then((pdf) => {
    pdfDoc = pdf;
    pdfPages.value = pdfDoc.numPages;
    nextTick(async () => {
      await renderPage(1); // 表示渲染第 1 页
    });
  });
}
function renderPage(num: any) {
  pdfDoc.getPage(num).then((page: any) => {
    const canvasId = "pdf-canvas-" + num; // 第num个canvas画布的id
    const canvas: any = document.getElementById(canvasId);
    const ctx: any = canvas.getContext("2d");
    const dpr = window.devicePixelRatio || 1;
    const bsr =
      ctx.webkitBackingStorePixelRatio ||
      ctx.mozBackingStorePixelRatio ||
      ctx.msBackingStorePixelRatio ||
      ctx.oBackingStorePixelRatio ||
      ctx.backingStorePixelRatio ||
      1;
    const ratio = dpr / bsr;
    const viewport = page.getViewport({ scale: props.pdfScale });
    canvas.width = viewport.width * ratio;
    canvas.height = viewport.height * ratio;
    canvas.style.width = viewport.width + "px";
    canvas.style.height = viewport.height + "px";
    ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
    const renderContext = {
      canvasContext: ctx,
      viewport: viewport,
    };
    page.render(renderContext);
    loading.value = false;
    // 在第num页渲染完毕后，递归调用renderPage方法，去渲染下一页，直到所有页面渲染完毕为止
    if (num < pdfPages.value) {
      renderPage(num + 1);
    }
  });
}
watch(
  () => props.url,
  (n, o) => {
    if (n) {
      loadFile(n);
    }
  },
  { deep: true, immediate: true }
);
</script>

<style lang="scss" scoped></style>
